/**
 * 
 */
package edu.cmu.lti.lm.dt;

import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;

/**
 * @author qing
 *
 */
public class TreeNode implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 3467419649057927730L;
	private TreeNode posChild=null, negChild=null;
	protected Map<String, Double> posDist=null, negDist=null; 
	private Question question;
	public TreeNode(TreeNode posChild, TreeNode negChild, Question question) {
		super();
		this.posChild = posChild;
		this.negChild = negChild;
		this.question = question;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((negChild == null) ? 0 : negChild.hashCode());
		result = prime * result
				+ ((posChild == null) ? 0 : posChild.hashCode());
		result = prime * result
				+ ((question == null) ? 0 : question.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final TreeNode other = (TreeNode) obj;
		if (negChild == null) {
			if (other.negChild != null)
				return false;
		} else if (!negChild.equals(other.negChild))
			return false;
		if (posChild == null) {
			if (other.posChild != null)
				return false;
		} else if (!posChild.equals(other.posChild))
			return false;
		if (question == null) {
			if (other.question != null)
				return false;
		} else if (!question.equals(other.question))
			return false;
		return true;
	}
	public TreeNode getPosChild() {
		return posChild;
	}
	public void setPosChild(TreeNode posChild) {
		this.posChild = posChild;
	}
	public TreeNode getNegChild() {
		return negChild;
	}
	public void setNegChild(TreeNode negChild) {
		this.negChild = negChild;
	}
	public Question getQuestion() {
		return question;
	}
	public void setQuestion(Question question) {
		this.question = question;
	}
	
	public void printTree(String indent){
		String moreindent =indent + "\t";
		System.out.print(indent);
		System.out.print("if ");
		System.out.print(question.getFeature().getName());
		Iterator<String> it = question.iterator();
		System.out.print(" ( ");
		while(it.hasNext()){
			System.out.print("\"" + it.next()+"\"");
			System.out.print(" ");
		}
		System.out.println(indent+" ) then");
		if( posChild == null ){
			System.out.println(moreindent+"Leaf");
		}else{
			posChild.printTree(moreindent);
		}
		System.out.println(indent + "else");
		if( negChild == null ){
			System.out.println(moreindent+"Leaf");
		}else{
			negChild.printTree(moreindent);
		}
		System.out.println(indent + "endif");
	}
	private static double l2 = Math.log(2);
	
	public double getLogProb(Entry c){
		// classify
		
		if(question.classify(c)){
			if(posDist!=null){
				Double d = posDist.get(c.getWord());
				if(d!=null)
					return Math.log(d)/l2;
				else
					return -60;
			}else{
				if(posChild!=null)
					return posChild.getLogProb(c);
				else
					return -60;
			}
		}else{
			if(negDist!=null){
				Double d = negDist.get(c.getWord());
				if(d!=null)
					return Math.log(d)/l2;
				else
					return -60;
			}else{
				if(negChild!=null)
					return negChild.getLogProb(c);
				else
					return -60;
			}			
		}
	}
}
